"""
设备管理模块
实现设备注册、状态监控、参数配置等功能
"""
import uuid
from typing import List, Dict, Any, Optional
from datetime import datetime, timedelta
import logging

from .models import (
    DeviceIn, DeviceOut, DeviceStatusUpdate, DeviceStatus,
    UserRole, DeviceStats
)

logger = logging.getLogger(__name__)


class DeviceService:
    """设备管理服务"""
    
    def __init__(self):
        self.devices = {}  # 模拟数据库存储
        self.device_status_history = {}  # 设备状态历史
        self.device_configs = {}  # 设备配置
    
    def register_device(self, device_data: DeviceIn, owner_id: str) -> DeviceOut:
        """注册设备"""
        try:
            device_id = device_data.device_id
            
            # 检查设备是否已存在
            if device_id in self.devices:
                raise ValueError(f"设备 {device_id} 已存在")
            
            # 创建设备对象
            device = DeviceOut(
                device_id=device_id,
                device_name=device_data.device_name,
                device_model=device_data.device_model,
                team_id=device_data.team_id,
                owner_id=owner_id,
                os_version=device_data.os_version,
                app_version=device_data.app_version,
                firmware_version=device_data.firmware_version,
                hardware_version=device_data.hardware_version,
                status=DeviceStatus.ACTIVE,
                last_seen=datetime.utcnow(),
                battery_level=None,
                temperature=None,
                storage_usage=None,
                cpu_usage=None,
                memory_usage=None,
                location_latitude=None,
                location_longitude=None,
                location_accuracy=None,
                is_active=True,
                created_at=datetime.utcnow(),
                updated_at=datetime.utcnow()
            )
            
            # 保存设备
            self.devices[device_id] = device
            
            # 初始化状态历史
            self.device_status_history[device_id] = []
            
            # 初始化默认配置
            self.device_configs[device_id] = self._get_default_config()
            
            logger.info(f"设备注册成功: {device_id}, 名称: {device_data.device_name}")
            return device
            
        except Exception as e:
            logger.error(f"设备注册失败: {str(e)}")
            raise
    
    def get_device(self, device_id: str, user_id: str) -> Optional[DeviceOut]:
        """获取设备信息"""
        try:
            device = self.devices.get(device_id)
            if not device:
                return None
            
            # 检查用户权限
            if not self._check_device_access(device, user_id):
                return None
            
            return device
            
        except Exception as e:
            logger.error(f"获取设备信息失败: {str(e)}")
            return None
    
    def update_device_status(self, status_update: DeviceStatusUpdate, user_id: str) -> Optional[DeviceOut]:
        """更新设备状态"""
        try:
            device = self.devices.get(status_update.device_id)
            if not device:
                return None
            
            # 检查用户权限
            if not self._check_device_access(device, user_id):
                return None
            
            # 更新设备状态
            device.status = status_update.status
            device.battery_level = status_update.battery_level
            device.temperature = status_update.temperature
            device.storage_usage = status_update.storage_usage
            device.cpu_usage = status_update.cpu_usage
            device.memory_usage = status_update.memory_usage
            device.location_latitude = status_update.location_latitude
            device.location_longitude = status_update.location_longitude
            device.location_accuracy = status_update.location_accuracy
            device.last_seen = datetime.utcnow()
            device.updated_at = datetime.utcnow()
            
            # 记录状态历史
            self._record_status_history(device)
            
            logger.info(f"设备状态更新成功: {status_update.device_id}")
            return device
            
        except Exception as e:
            logger.error(f"设备状态更新失败: {str(e)}")
            return None
    
    def get_team_devices(self, team_id: str, user_id: str, 
                        status: Optional[DeviceStatus] = None,
                        page: int = 1, page_size: int = 20) -> Dict[str, Any]:
        """获取团队设备列表"""
        try:
            # 过滤设备
            filtered_devices = []
            for device in self.devices.values():
                if device.team_id != team_id:
                    continue
                
                # 检查用户权限
                if not self._check_device_access(device, user_id):
                    continue
                
                # 应用状态过滤器
                if status and device.status != status:
                    continue
                
                filtered_devices.append(device)
            
            # 排序（按最后在线时间倒序）
            filtered_devices.sort(key=lambda x: x.last_seen or datetime.min, reverse=True)
            
            # 分页
            total = len(filtered_devices)
            start = (page - 1) * page_size
            end = start + page_size
            devices_page = filtered_devices[start:end]
            
            return {
                'devices': devices_page,
                'total': total,
                'page': page,
                'page_size': page_size,
                'total_pages': (total + page_size - 1) // page_size
            }
            
        except Exception as e:
            logger.error(f"获取团队设备失败: {str(e)}")
            return {'devices': [], 'total': 0, 'page': page, 'page_size': page_size, 'total_pages': 0}
    
    def get_device_status_history(self, device_id: str, user_id: str, 
                                 hours: int = 24) -> List[Dict[str, Any]]:
        """获取设备状态历史"""
        try:
            device = self.devices.get(device_id)
            if not device:
                return []
            
            # 检查用户权限
            if not self._check_device_access(device, user_id):
                return []
            
            # 获取历史记录
            history = self.device_status_history.get(device_id, [])
            
            # 过滤时间范围
            cutoff_time = datetime.utcnow() - timedelta(hours=hours)
            filtered_history = [h for h in history if h['timestamp'] >= cutoff_time]
            
            return filtered_history
            
        except Exception as e:
            logger.error(f"获取设备状态历史失败: {str(e)}")
            return []
    
    def get_device_statistics(self, device_id: str, user_id: str) -> Optional[DeviceStats]:
        """获取设备统计信息"""
        try:
            device = self.devices.get(device_id)
            if not device:
                return None
            
            # 检查用户权限
            if not self._check_device_access(device, user_id):
                return None
            
            # 模拟统计数据（实际应该从数据库查询）
            stats = DeviceStats(
                device_id=device_id,
                device_name=device.device_name or "未知设备",
                total_records=1000,  # 模拟数据
                avg_signal_strength=-85.5,  # 模拟数据
                last_analysis=datetime.utcnow() - timedelta(hours=2),  # 模拟数据
                ai_confidence_avg=0.85,  # 模拟数据
                anomaly_count=5,  # 模拟数据
                status=device.status
            )
            
            return stats
            
        except Exception as e:
            logger.error(f"获取设备统计失败: {str(e)}")
            return None
    
    def get_device_config(self, device_id: str, user_id: str) -> Optional[Dict[str, Any]]:
        """获取设备配置"""
        try:
            device = self.devices.get(device_id)
            if not device:
                return None
            
            # 检查用户权限
            if not self._check_device_access(device, user_id):
                return None
            
            return self.device_configs.get(device_id, {})
            
        except Exception as e:
            logger.error(f"获取设备配置失败: {str(e)}")
            return None
    
    def update_device_config(self, device_id: str, config: Dict[str, Any], user_id: str) -> bool:
        """更新设备配置"""
        try:
            device = self.devices.get(device_id)
            if not device:
                return False
            
            # 检查用户权限
            if not self._check_device_config_permission(device, user_id):
                return False
            
            # 更新配置
            self.device_configs[device_id] = config
            
            # 更新设备时间
            device.updated_at = datetime.utcnow()
            
            logger.info(f"设备配置更新成功: {device_id}")
            return True
            
        except Exception as e:
            logger.error(f"设备配置更新失败: {str(e)}")
            return False
    
    def get_offline_devices(self, team_id: str, user_id: str, 
                           offline_threshold_minutes: int = 30) -> List[DeviceOut]:
        """获取离线设备列表"""
        try:
            offline_devices = []
            cutoff_time = datetime.utcnow() - timedelta(minutes=offline_threshold_minutes)
            
            for device in self.devices.values():
                if device.team_id != team_id:
                    continue
                
                # 检查用户权限
                if not self._check_device_access(device, user_id):
                    continue
                
                # 检查是否离线
                if device.last_seen and device.last_seen < cutoff_time:
                    offline_devices.append(device)
            
            # 按离线时间排序
            offline_devices.sort(key=lambda x: x.last_seen or datetime.min)
            
            return offline_devices
            
        except Exception as e:
            logger.error(f"获取离线设备失败: {str(e)}")
            return []
    
    def get_device_alerts(self, team_id: str, user_id: str) -> List[Dict[str, Any]]:
        """获取设备告警"""
        try:
            alerts = []
            
            for device in self.devices.values():
                if device.team_id != team_id:
                    continue
                
                # 检查用户权限
                if not self._check_device_access(device, user_id):
                    continue
                
                # 检查各种告警条件
                device_alerts = self._check_device_alerts(device)
                alerts.extend(device_alerts)
            
            # 按严重程度和时间排序
            alerts.sort(key=lambda x: (x['severity'], x['timestamp']), reverse=True)
            
            return alerts
            
        except Exception as e:
            logger.error(f"获取设备告警失败: {str(e)}")
            return []
    
    def _check_device_access(self, device: DeviceOut, user_id: str) -> bool:
        """检查设备访问权限"""
        # 这里应该检查用户角色和团队权限
        # 简化实现：团队成员都可以访问
        return True
    
    def _check_device_config_permission(self, device: DeviceOut, user_id: str) -> bool:
        """检查设备配置权限"""
        # 设备所有者或管理员可以配置
        return (device.owner_id == user_id or self._is_admin(user_id))
    
    def _is_admin(self, user_id: str) -> bool:
        """检查是否为管理员（模拟实现）"""
        # 这里应该从数据库查询用户角色
        return False
    
    def _record_status_history(self, device: DeviceOut):
        """记录设备状态历史"""
        if device.device_id not in self.device_status_history:
            self.device_status_history[device.device_id] = []
        
        status_record = {
            'timestamp': datetime.utcnow(),
            'status': device.status.value,
            'battery_level': device.battery_level,
            'temperature': device.temperature,
            'storage_usage': device.storage_usage,
            'cpu_usage': device.cpu_usage,
            'memory_usage': device.memory_usage,
            'location_latitude': float(device.location_latitude) if device.location_latitude else None,
            'location_longitude': float(device.location_longitude) if device.location_longitude else None,
            'location_accuracy': device.location_accuracy
        }
        
        self.device_status_history[device.device_id].append(status_record)
        
        # 只保留最近1000条记录
        if len(self.device_status_history[device.device_id]) > 1000:
            self.device_status_history[device.device_id] = self.device_status_history[device.device_id][-1000:]
    
    def _get_default_config(self) -> Dict[str, Any]:
        """获取默认设备配置"""
        return {
            'sampling_rate': 1000,  # 采样率 (Hz)
            'signal_threshold': -100,  # 信号阈值 (dBm)
            'ai_confidence_threshold': 0.8,  # AI置信度阈值
            'data_retention_days': 30,  # 数据保留天数
            'auto_export': False,  # 自动导出
            'alert_enabled': True,  # 告警启用
            'location_tracking': True,  # 位置跟踪
            'battery_alert_threshold': 20,  # 电量告警阈值
            'temperature_alert_threshold': 60,  # 温度告警阈值
            'storage_alert_threshold': 90  # 存储告警阈值
        }
    
    def _check_device_alerts(self, device: DeviceOut) -> List[Dict[str, Any]]:
        """检查设备告警"""
        alerts = []
        current_time = datetime.utcnow()
        
        # 离线告警
        if device.last_seen:
            offline_time = current_time - device.last_seen
            if offline_time > timedelta(minutes=30):
                alerts.append({
                    'device_id': device.device_id,
                    'device_name': device.device_name,
                    'alert_type': 'offline',
                    'severity': 'high' if offline_time > timedelta(hours=2) else 'medium',
                    'message': f"设备离线 {offline_time}",
                    'timestamp': current_time
                })
        
        # 电量告警
        if device.battery_level is not None and device.battery_level < 20:
            alerts.append({
                'device_id': device.device_id,
                'device_name': device.device_name,
                'alert_type': 'battery_low',
                'severity': 'high' if device.battery_level < 10 else 'medium',
                'message': f"电量不足: {device.battery_level}%",
                'timestamp': current_time
            })
        
        # 温度告警
        if device.temperature is not None and device.temperature > 60:
            alerts.append({
                'device_id': device.device_id,
                'device_name': device.device_name,
                'alert_type': 'temperature_high',
                'severity': 'high' if device.temperature > 80 else 'medium',
                'message': f"温度过高: {device.temperature}°C",
                'timestamp': current_time
            })
        
        # 存储告警
        if device.storage_usage is not None and device.storage_usage > 90:
            alerts.append({
                'device_id': device.device_id,
                'device_name': device.device_name,
                'alert_type': 'storage_full',
                'severity': 'high' if device.storage_usage > 95 else 'medium',
                'message': f"存储空间不足: {device.storage_usage}%",
                'timestamp': current_time
            })
        
        # 设备状态告警
        if device.status == DeviceStatus.ERROR:
            alerts.append({
                'device_id': device.device_id,
                'device_name': device.device_name,
                'alert_type': 'device_error',
                'severity': 'critical',
                'message': "设备状态异常",
                'timestamp': current_time
            })
        
        return alerts